package com.loper7.base.utils.img;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.widget.ImageView;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
import com.bumptech.glide.load.resource.bitmap.FitCenter;
import com.bumptech.glide.load.resource.bitmap.TransformationUtils;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.SimpleTarget;
import com.bumptech.glide.request.transition.Transition;
import com.loper7.base.BuildConfig;
import com.loper7.base.R;
import com.loper7.base.utils.BaseApplication;
import com.loper7.base.utils.Logger;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;

/**
 * @author loper7
 * @Description: 图片加载类
 * @date 2016/11/1 11:50
 */
public class ImageLoad {


    /**
     * 加载配置
     *
     * @param soildImage 占位图
     * @return
     */
    public static RequestOptions getOptions(int soildImage) {
        return new RequestOptions()
                .placeholder(soildImage)
                .error(soildImage)
                .skipMemoryCache(false)
                .diskCacheStrategy(DiskCacheStrategy.ALL);
    }

    /**
     * 加载配置
     *
     * @return
     */
    public static RequestOptions getOptionsNoImgae() {
        return new RequestOptions()
                .skipMemoryCache(false)
                .diskCacheStrategy(DiskCacheStrategy.ALL);
    }


    /**
     * 加载图片
     *
     * @param context    上下文
     * @param imageView  容器
     * @param object     图片
     * @param soildImage 占位图
     */
    public static void load(Context context, ImageView imageView, Object object, int soildImage) {

        Glide.with(context)
                .load(object)
                .apply(getOptions(soildImage))
                .thumbnail(0.5f)
                .into(imageView);
    }

    /**
     * 加载图片
     *
     * @param context   上下文
     * @param imageView 容器
     * @param object    图片
     */
    public static void load(Context context, ImageView imageView, Object object, RequestListener requestListener) {

        Glide.with(context)
                .load(object)
                .apply(getOptionsNoImgae())
                .thumbnail(0.1f)
                .listener(requestListener)
                .into(imageView);
    }

    /**
     * 加载图片
     *
     * @param activity   activity
     * @param imageView  容器
     * @param object     图片
     * @param soildImage 占位图
     */
    public static void load(Activity activity, ImageView imageView, Object object, int soildImage) {
        load(activity.getApplicationContext(), imageView, object, soildImage);
    }

    /**
     * 加载图片
     *
     * @param context   上下文
     * @param imageView 容器
     * @param object    图片
     */
    public static void load(Context context, ImageView imageView, Object object) {
        load(context, imageView, object, R.drawable.ic_default_icon);
    }


    /**
     * 加载图片
     *
     * @param context    上下文
     * @param imageView  容器
     * @param object     图片
     * @param soildImage 占位图
     */
    public static void loadCircle(Context context, ImageView imageView, Object object, int soildImage) {

        Glide.with(context)
                .load(object)
                .apply(getOptions(soildImage)
                        .transform(new GlideCircleTransform(context)))
                .thumbnail(0.5f)
                .into(imageView);
    }

    /**
     * 加载图片
     *
     * @param context   上下文
     * @param imageView 容器
     * @param object    图片
     */
    public static void loadCircle(Context context, ImageView imageView, Object object) {

        loadCircle(context, imageView, object, R.drawable.ic_default_header);
    }


    /**
     * 加载图片
     *
     * @param context    上下文
     * @param imageView  容器
     * @param object     图片网络地址
     * @param soildImage 占位图
     */
    public static void loadRound(Context context, int round, ImageView imageView, Object object, int soildImage) {

        Glide.with(context)
                .load(object)
                .apply(getOptions(soildImage)
                        .transform(new GlideRoundTransform(context, round)))
                .thumbnail(0.5f)
                .into(imageView);
    }

    /**
     * 加载图片
     *
     * @param context   上下文
     * @param imageView 容器
     * @param object    图片网络地址
     */
    public static void loadRound(Context context, ImageView imageView, Object object, int soildImage) {
        loadRound(context, 4, imageView, object, soildImage);
    }

    /**
     * 加载图片
     *
     * @param context   上下文
     * @param imageView 容器
     * @param object    图片网络地址
     */
    public static void loadRound(Context context, ImageView imageView, Object object) {
        loadRound(context, 4, imageView, object, R.drawable.ic_default_icon);
    }


    /**
     * 加载指定宽度图片
     *
     * @param context    上下文
     * @param imageView  容器
     * @param object     图片网络地址
     * @param soildImage 占位图
     */
    @SuppressLint("CheckResult")
    public static void loadOverrideRound(Context context, int round, int width, ImageView imageView, Object object, int soildImage) {

        Glide.with(context)
                .load(object)
                .apply(getOptions(soildImage)
                        .override(width, Integer.MAX_VALUE))
//                        .transform(new GlideRoundTransform(context, 4)))
                .thumbnail(0.5f)
                .into(imageView);
    }

    /**
     * 加载指定宽度图片
     *
     * @param context    上下文
     * @param imageView  容器
     * @param object     图片网络地址
     * @param soildImage 占位图
     */
    public static void loadOverrideRound(Context context, int width, ImageView imageView, Object object, int soildImage) {
        loadOverrideRound(context, 4, width, imageView, object, soildImage);
    }


    /**
     * 保存图片
     *
     * @param context
     * @param url
     */
    public static void savePicture(final Context context, final String url) {
        Glide.with(context).asBitmap().load(url).into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                saveImageToGallery(context, url, resource);
            }
        });
    }


    /**
     * 保存图片至相册
     *
     * @param context
     * @param bmp
     */
    public static void saveImageToGallery(Context context, String url, Bitmap bmp) {
        // 首先保存图片
        File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoluteFile();//注意小米手机必须这样获得public绝对路径
        String fName = context.getString(R.string.app_name);
        File appDir = new File(file, fName);
        if (!appDir.exists()) {
            appDir.mkdirs();
        }

        Logger.e("saveImageToGallery：" + url2ImageName(url));
        File currentFile = new File(appDir, url2ImageName(url));

        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(currentFile);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
            fos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        // 最后通知图库更新
        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                Uri.fromFile(new File(currentFile.getPath()))));
    }

    /**
     * 保存图片
     *
     * @param context
     * @param url
     */
    public static void savePictureToast(final Context context, final String url) {
        Glide.with(context).asBitmap().load(url).into(new SimpleTarget<Bitmap>() {
            @Override
            public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                saveImageToGallery(context, url, resource);
                Toast.makeText(context.getApplicationContext(), "图片已保存至相册", Toast.LENGTH_SHORT).show();
            }
        });
    }


    /**
     * glide加载圆形图
     */
    public static class GlideCircleTransform extends BitmapTransformation {
        private static final int VERSION = 1;
        private static final String ID = BuildConfig.APPLICATION_ID + "GlideCircleTransform." + VERSION;
        private static final byte[] ID_BYTES = ID.getBytes(CHARSET);

        public GlideCircleTransform(Context context) {
            super(context);
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            Bitmap bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);
            return circleCrop(pool, bitmap);
        }

        private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
            if (source == null) return null;

            int size = Math.min(source.getWidth(), source.getHeight());
            int x = (source.getWidth() - size) / 2;
            int y = (source.getHeight() - size) / 2;

            // TODO this could be acquired from the pool too
            Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);

            Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
            if (result == null) {
                result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
            }

            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
            paint.setAntiAlias(true);
            float r = size / 2f;
            canvas.drawCircle(r, r, r, paint);
            return result;
        }


        @Override
        public boolean equals(Object o) {
            return o instanceof GlideCircleTransform;
        }


        @Override
        public int hashCode() {
            return ID.hashCode();
        }


        @Override
        public void updateDiskCacheKey(MessageDigest messageDigest) {
            messageDigest.update(ID_BYTES);
        }
    }

    /**
     * glide加载圆角图片
     */
    public static class GlideRoundTransform extends BitmapTransformation {

        private float radius = 0f;
        private static final int VERSION = 1;
        private static final String ID = BuildConfig.APPLICATION_ID + "GlideRoundTransform." + VERSION;
        private static final byte[] ID_BYTES = ID.getBytes(CHARSET);


        public GlideRoundTransform(Context context, int dp) {
            super(context);
            this.radius = Resources.getSystem().getDisplayMetrics().density * dp;
        }

        @Override
        protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
            Bitmap bitmap = TransformationUtils.centerCrop(pool, toTransform, outWidth, outHeight);
            return roundCrop(pool, bitmap);
        }

        private Bitmap roundCrop(BitmapPool pool, Bitmap source) {
            if (source == null) return null;

            Bitmap result = pool.get(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            if (result == null) {
                result = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Bitmap.Config.ARGB_8888);
            }

            Canvas canvas = new Canvas(result);
            Paint paint = new Paint();
            paint.setShader(new BitmapShader(source, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
            paint.setAntiAlias(true);
            RectF rectF = new RectF(0f, 0f, source.getWidth(), source.getHeight());
            canvas.drawRoundRect(rectF, radius, radius, paint);
            return result;
        }

        @Override
        public boolean equals(Object o) {
            return o instanceof GlideRoundTransform;
        }


        @Override
        public int hashCode() {
            return ID.hashCode();
        }


        @Override
        public void updateDiskCacheKey(MessageDigest messageDigest) {
            messageDigest.update(ID_BYTES);
        }

    }


    /**
     * 获取url内图片名称
     *
     * @param url
     * @return
     */
    public static String url2ImageName(String url) {
        String[] uString = url.split("/");
        String fileName;
        if (uString.length > 1)
            fileName = TextUtils.isEmpty(uString[uString.length - 1]) ? System.currentTimeMillis() + "" : uString[uString.length - 1];
        else
            fileName = TextUtils.isEmpty(uString[0]) ? System.currentTimeMillis() + "" : uString[0];

        if (!fileName.endsWith(".jpg") && !fileName.endsWith(".png") && !fileName.endsWith(".gif") && !fileName.endsWith(".jpeg")) {
            fileName += ".jpg";
        }
        return fileName;
    }

    /**
     * 判断图片是否已下载
     *
     * @param strFile
     * @return
     */
    public static boolean fileIsExists(Context context, String strFile) {
        File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsoluteFile();//注意小米手机必须这样获得public绝对路径
        String fName = file.getPath() + "/" + context.getString(R.string.app_name) + "/" + strFile;
        Logger.e("fileIsExists：" + fName);
        File appDir = new File(fName);
        try {
            if (!appDir.exists())
                return false;
        } catch (Exception e) {
            return false;
        }
        return true;

    }
}